package cn.cuilan.test.thread;

/**
 * 三线程交替打印
 * synchronized+wait/notify 方式实现
 *
 * @author zhangyan
 * @since 2023/3/9
 */
public class SynchronizedWaitNotify {

    private int num;
    private static final Object LOCK = new Object();

    /**
     * 交替打印
     * <p>
     * 线程同时启动，变量 num 初始值为0，
     * 线程拿到 LOCK 锁对象后，判断 num 是否等于 targetNum，
     * 不相等：进入 while 循环，执行 LOCK.wait()，将线程阻塞，释放 LOCK 锁，
     * 相等：执行输出，num++，唤醒其他线程。
     *
     * @param targetNum 目标线程
     * @param context   输出内容
     */
    public void print(int targetNum, String context) {
        for (int i = 0; i < 2; i++) {
            synchronized (LOCK) {
                while (num % 4 != targetNum) {
                    try {
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + ": " + context);
                num++;
                LOCK.notifyAll();
            }
        }
    }

    public static void main(String[] args) {
        SynchronizedWaitNotify swn = new SynchronizedWaitNotify();
        new Thread(() -> swn.print(0, "A"), "Thread-a").start();
        new Thread(() -> swn.print(1, "B"), "Thread-b").start();
        new Thread(() -> swn.print(2, "C"), "Thread-c").start();
        new Thread(() -> swn.print(3, "D"), "Thread-d").start();
    }

}
